/*
 * iacmd.cpp
 *
 *  Created on: 2013/01/31
 *      Author: fit
 */

#include "iacmd.h"
#include <stdlib.h>
#include <string.h>

///
///
///
iacmd::iacmd()
: m_size(DEF_BUF_SIZE)
{
	m_buf = (unsigned char*)calloc(m_size, 1);
}

///
///
///
iacmd::iacmd(const void* _buf, unsigned int _n)
: m_size(_n)
{
	m_buf = (unsigned char*)calloc(m_size, 1);
	memcpy(m_buf, _buf, m_size);
}

///
///
///
iacmd::~iacmd()
{
	free(m_buf);
	m_size = 0;
}

///
///
///
void iacmd::settype(cmd_type type)
{
	m_buf[0] = type;
}

///
///
///
void iacmd::add(unsigned char param, unsigned char cnt/* = 0*/, void* value/* = NULL*/)
{
	// get set index
	unsigned int index = sizeof(CMD_HEAD);
	for (unsigned char i = 0; i < m_buf[1]; i++)
	{
		index += sizeof(SET_DATA) + ((SET_DATA*)(m_buf + index))->cnt;
	}

	// check size
	unsigned int need_size = index + sizeof(SET_DATA) + cnt;
	if (need_size  > m_size)
	{
		m_buf = (unsigned char*)realloc(m_buf, need_size);
	}

	// set data head
	m_buf[index]= param;
	m_buf[index + 1] = cnt;
	// set data value
	if (value) memcpy(m_buf + index + sizeof(CMD_HEAD), value, cnt);
	//
	m_buf[1]++;
}

unsigned int iacmd::read(void* _buf, unsigned int _n) const
{
	unsigned int res = m_size;
	if (res > _n) res = _n;

	memcpy(_buf, m_buf, res);
	return res;
}

///
///
///
cmd_type iacmd::cmd() const
{
	return (cmd_type)m_buf[0];
}

///
///
///
unsigned char iacmd::count() const
{
	return m_buf[1];
}

///
///
///
const SET_DATA* iacmd::operator [] (unsigned int index) const
{
	if (index > m_buf[1]) return NULL;

	unsigned int _index = sizeof(CMD_HEAD);
	for (unsigned char i = 0; i < index; i++)
	{
		_index += sizeof(SET_DATA) + ((SET_DATA*)(m_buf + _index))->cnt;
	}

	return (SET_DATA*)(m_buf + _index);
}
